#include "helper.h"

QString getLocalIP()
{
    QList<QHostAddress> list = QNetworkInterface::allAddresses();

    foreach(QHostAddress address, list) {
        if(address.protocol() == QAbstractSocket::IPv4Protocol) {
            qDebug() << QString("ip:%1").arg(address.toString());
        }
    }

    foreach(QHostAddress address, list) {
        if(address.protocol() == QAbstractSocket::IPv4Protocol) {
            if(address.toString().contains("127.0.")) {
                continue;
            } else {
                return address.toString();
            }
        }
    }
    return 0;
}

QString executeLinuxCmd(QString strCmd) {
    QProcess p;
    p.start("bash", QStringList() << "-c" << strCmd);
    p.waitForFinished();
    QString strResult = p.readAllStandardOutput();
    return strResult;
}

unsigned int ip2int(QString ip)
{
    QStringList sl = ip.split('.');
    unsigned int r = 0;
    foreach(QString s,sl)
    {
        r <<= 8;
        r |= s.toUInt();
    }

    return r;
}

QString int2ip(unsigned int ip)
{
    return QString::number((ip >> 24) & 0xff) + "." + QString::number((ip >> 16) & 0xff)
           + "." + QString::number((ip >> 8) & 0xff) + "." + QString::number(ip & 0xff);
}

QString byteArrayToHexStr(const QByteArray &data)
{
    QString temp = "";
    QString hex = data.toHex();

    for (int i = 0; i < hex.length(); i = i + 2) {
        temp += hex.mid(i, 2) + " ";
    }

    return temp.trimmed().toUpper();
}

QByteArray hexStrToByteArray(const QString &str)
{
    QByteArray senddata;
    int hexdata, lowhexdata;
    int hexdatalen = 0;
    int len = str.length();
    char lstr, hstr;
    senddata.resize(len/2);
    for(int i = 0; i < len;) {
        hstr = str.at(i).toLatin1();
        if(hstr == ' ') {
            i++;
            continue;
        }
        i++;
        if(i >= len) {
            break;
        }
        lstr = str.at(i).toLatin1();
        hexdata = convertHexChar(hstr);
        lowhexdata = convertHexChar(lstr);

        if((hexdata == 16) || (lowhexdata == 16)) {
            break;
        } else {
            hexdata = hexdata * 16 + lowhexdata;
        }

        i++;
        senddata[hexdatalen] = (char) hexdata;
        hexdatalen++;
    }
    senddata.resize(hexdatalen);
    return senddata;
}

char convertHexChar(char ch)
{
    if((ch >= '0') && (ch <= '9')) {
        return ch - 0x30;
    } else if((ch >= 'A') && (ch <= 'F')) {
        return ch - 'A' + 10;
    } else if((ch >= 'a') && (ch <= 'f')) {
        return ch - 'a' + 10;
    } else {
        return (-1);
    }
}

quint8 XOR_Cal(unsigned char *data, unsigned int len)
{
    quint8 xorValue = data[0];
    for(unsigned i = 1; i < len; i++) {
        xorValue ^= data[i];
    }

    return xorValue;
}

quint8 sumData(QByteArray &data)
{
    quint8 sum = 0x00;
    for(quint8 i = 1; i < data.size(); i++) {
        sum += data.at(i);
    }
    return sum;
}

QString getAppId(QString netId, int stationId, QString laneId)
{
    QString newNetId = fillWithZero(netId, 4);
    QString newStatId = QString("%1").arg(stationId, 4, 16, QLatin1Char('0'));
    QString newLaneId = fillWithZero(laneId, 2);

    QString appId = QString("%1%2%3").arg(newNetId).arg(newStatId).arg(newLaneId).toUpper();
    return appId;
}

QString fillWithZero(const QString &src, int length)
{
    QString pattern;
    for(int i = 0; i < length; i++)
        pattern.append("0");
    return (pattern+src).right(length);
}

void encodeutf82gb2312(QString str, QByteArray &outArr)
{
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    if(codec->canEncode(str)) {
        QByteArray tmpArr;
        tmpArr = codec->fromUnicode(str);
        for(int i = 0, size = tmpArr.length(); i < size; i++) {
            char ch = tmpArr.at(i);
            if(ch < 128 && ch > 0) {
                outArr.append(ch);
            } else {
                uchar low = ch & 0xff;
                outArr.append((char)low);
                //                char c[3];
                //                sprintf(c, "%02x", low);
                //                outArr.append(c);
            }
        }
    }

    QByteArray addArray;
    addArray.fill((char)0x20, 16-outArr.size());
    outArr.append(addArray);
}


void getLedBoardBytes(QString &text, QByteArray &outArr)
{
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    if(codec->canEncode(text)) {
        QByteArray tmpArr;
        tmpArr = codec->fromUnicode(text);
        for(int i = 0, size = tmpArr.length(); i < size; i++) {
            char ch = tmpArr.at(i);
            if(ch < 128 && ch > 0) {
                outArr.append(ch);
            } else {
                uchar low = ch & 0xff;
                outArr.append((char)low);
            }
        }
    }
}

QString genMsgId(QString appId)
{
    QDateTime curTime = QDateTime::currentDateTime();
    qint64 timestamp = curTime.toMSecsSinceEpoch();/// 毫秒级
    QString msgId = QString("%1-%2").arg(appId).arg(timestamp);

    return msgId;
}

void convertUTF8ToGB2312_16(char *str, quint8 strLen, QByteArray &outArr)
{
    QString lineText = QString::fromUtf8(str);
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    if(codec->canEncode(lineText)) {
        QByteArray tmpArr;
        tmpArr = codec->fromUnicode(lineText);
        for(int i = 0, size = tmpArr.length(); i < size; i++) {
            char ch = tmpArr.at(i);
            if(ch < 128 && ch > 0) {
                outArr.append(ch);
            } else {
                uchar low = ch & 0xff;
                outArr.append((char)low);
            }
        }
    }

    QByteArray addArray;
    addArray.fill((char)0x20, 16-outArr.size());
    outArr.append(addArray);
}

void convertUTF8ToGB2312(char *str, quint8 strLen, QByteArray &outArr)
{
    QString lineText = QString::fromUtf8(str);
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    if(codec->canEncode(lineText)) {
        QByteArray tmpArr;
        tmpArr = codec->fromUnicode(lineText);
        for(int i = 0, size = tmpArr.length(); i < size; i++) {
            char ch = tmpArr.at(i);
            if(ch < 128 && ch > 0) {
                outArr.append(ch);
            } else {
                uchar low = ch & 0xff;
                outArr.append((char)low);
            }
        }
    }
    //    QString convertStr = byteArrayToHexStr(outArr);
    //    qDebug() << QString("convert str = %s").arg(convertStr);
}

int bcd2decimal(int bcd)
{
    return (bcd+(bcd/10)*6);
}

int decimal2bcd(int decimal)
{
    return (decimal-(decimal>>4)*6);
}

quint32 get_BE32(const QByteArray &data)
{
    return ((data.at(0) << 24) | (data.at(1) << 16) | (data.at(2) << 8) | data.at(3));
}

quint32 get_LE32(const QByteArray &data)
{
    return (data.at(0) | (data.at(1) << 8) | (data.at(2) << 16) | (data.at(3) << 24));
}

void RemovePlateSpecChar(char *vehPlate, size_t vehLen, const char *sVlpText, int vlpLen) {
    memcpy(vehPlate, sVlpText, vlpLen);
}

QString GB2312toUnicode(const char *gb2312String)
{
    return QTextCodec::codecForName("GB2312")->toUnicode(gb2312String);
}

QByteArray UnicodetoGB2312(QString unicodeString)
{
    QString unicodeStr = QTextCodec::codecForName("GB2312")->fromUnicode(unicodeString);
    return unicodeStr.toLatin1();
}

QString UTF82GBK(QByteArray &inStr) {
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

    char *p = inStr.data();
    QString str = utf8->toUnicode(p);

    QByteArray utf8_bytes=gbk->fromUnicode(str);
    p = utf8_bytes.data();
    str = p;

    return str;
}

QString GBKtoUTF8(QByteArray &inStr)
{
    QTextCodec *gbk = QTextCodec::codecForName("gbk");
    QTextCodec *utf8 = QTextCodec::codecForName("UTF-8");

    char *p = inStr.data();
    QString str = gbk->toUnicode(p);

    QByteArray utf8_bytes=utf8->fromUnicode(str);
    p = utf8_bytes.data();
    str = p;

    return str;
}

bool WriteToFile(const QString &sFileName, char *lpBuffer, quint32 nBufferLen)
{
    QFile destFile(sFileName);
    if (!destFile.open(QFile::WriteOnly)) {
        return false;
    }

    QDataStream destStream(&destFile);
    quint32 rlt = destStream.writeRawData(lpBuffer, nBufferLen);
    if (rlt != nBufferLen) {
        destFile.close();
        return false;
    }
    destFile.close();
    return true;
}

bool WriteBufToFile(const char *pszImageName, quint8 *pcBuffer, unsigned nBufferLen)
{
    bool flag = true;
    FILE *file = fopen(pszImageName, "wb");
    if(nullptr == file) {
        return false;
    }
    int res = fwrite(pcBuffer, nBufferLen, 1, file);
    if (1 != res) {
        flag = false;
    }
    fclose(file);
    file = nullptr;
    return flag;
}

quint8 hex2ascii(quint8 hex)
{
    if (hex >= 0x00 && hex <= 0x09)
        return (hex + '0');	//'0'=0x30
    else if (hex >= 0x0A && hex <= 0x0F)
        return (hex - 0x0A + 'A');//强制大写
    return 0;
}

void u8Hex2ascii(quint8 hex, quint8 *ascii_buff)
{
    *ascii_buff = hex2ascii((hex >> 4) & 0x0F);
    *(ascii_buff + 1) = hex2ascii(hex & 0x0F);
}

void u16Hex2ascii(quint16 hex, quint8 *ascii_buff)
{
    quint8 i = 0;
    for (i = 0; i < 4; i++)
    {
        *(ascii_buff + 3 - i) = hex2ascii((hex >> (4*i)) & 0x000f);
    }
}

quint8 ascii2hex(quint8 ascii)
{
    if (ascii & 0x80) return ascii;

    if (ascii >= '0' && ascii <= '9')
        return (ascii - '0');
    else if (ascii >= 'A' && ascii <= 'F')	//ascii表示16进制，只有0-9 A-F
        return (ascii - 'A' + 0x0A);
    else if (ascii >= 'a' && ascii <= 'f')
        return (ascii - 'a' + 0x0A);
    return ascii;
}


void BCC_Cal(QByteArray &data, quint8 *ascii_buff)
{
    quint8 bcc = data.at(0);
    for(quint16 i = 1; i < data.length(); i++) {
        bcc ^= data.at(i);
    }

    u8Hex2ascii(bcc, ascii_buff);
}

bool RemoveFile(const QString &strFile) {
    if(QFile::exists(strFile))
        return QFile::remove(strFile);

    return true;
}

QString convertMsToFormat(long ms)
{
    int ss = 1000;
    int mi = ss * 60;
    int hh = mi * 60;
    int dd = hh * 24;

    long day = ms / dd;
    long hour = (ms - day * dd) / hh;
    long minute = (ms - day * dd - hour * hh) / mi;
    long second = (ms - day * dd - hour * hh - minute * mi) / ss;
    long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;

    QString hou = QString::number(hour,10);
    QString min = QString::number(minute,10);
    QString sec = QString::number(second,10);
    QString msec = QString::number(milliSecond,10);

    //qDebug() << "minute:" << min << "second" << sec << "ms" << msec <<endl;

    return hou + ":" + min + ":" + sec ;
}
